namespace Tools
{
    using System;
    using System.Collections;
    using System.IO.Ports;
    using System.Runtime.InteropServices;
    using System.Threading;
    
    public sealed class FR102
    {
        private const byte AnalogTestReg = 0x38;
        private const byte AutoTestReg = 0x36;
        private const byte BitFramingReg = 13;
        private const byte CollReg = 14;
        private const byte ComIEnReg = 2;
        private const byte ComIrqReg = 4;
        private const byte CommandReg = 1;
        private const byte ControlReg = 12;
        private const byte CRCResultRegL = 0x22;
        private const byte CRCResultRegM = 0x21;
        private const byte CWGsCfgReg = 40;
        private const byte DemodReg = 0x19;
        private const byte DivIrqReg = 5;
        private const byte DivlEnReg = 3;
        private const byte ErrorReg = 6;
        private const byte FIFODataReg = 9;
        private const byte FIFOLevelReg = 10;
        private const byte GsNReg = 0x27;
        private const byte MifareReg = 0x1c;
        private const byte ModeReg = 0x11;
        private const byte ModGsCfgReg = 0x29;
        private const byte ModWidthReg = 0x24;
        private const byte PCD_AUTHENT = 14;
        private const byte PCD_CALCCRC = 3;
        private const byte PCD_IDLE = 0;
        private const byte PCD_RECEIVE = 8;
        private const byte PCD_RESETPHASE = 15;
        private const byte PCD_TRANSCEIVE = 12;
        private const byte PCD_TRANSMIT = 4;
        private const byte PICC_ANTICOLL1 = 0x93;
        private const byte PICC_ANTICOLL2 = 0x95;
        private const byte PICC_AUTHENT1A = 0x60;
        private const byte PICC_AUTHENT1B = 0x61;
        private const byte PICC_DECREMENT = 0xc0;
        private const byte PICC_HALT = 80;
        private const byte PICC_INCREMENT = 0xc1;
        private const byte PICC_READ = 0x30;
        private const byte PICC_REQALL = 0x52;
        private const byte PICC_REQIDL = 0x26;
        private const byte PICC_RESTORE = 0xc2;
        private const byte PICC_TRANSFER = 0xb0;
        private const byte PICC_WRITE = 160;
        private const byte RFCfgReg = 0x26;
        private const byte RFU00 = 0;
        private const byte RFU0F = 15;
        private const byte RFU10 = 0x10;
        private const byte RFU1A = 0x1a;
        private const byte RFU1B = 0x1b;
        private const byte RFU1D = 0x1d;
        private const byte RFU1E = 30;
        private const byte RFU20 = 0x20;
        private const byte RFU23 = 0x23;
        private const byte RFU25 = 0x25;
        private const byte RFU30 = 0x30;
        private const byte RFU3C = 60;
        private const byte RFU3D = 0x3d;
        private const byte RFU3E = 0x3e;
        private const byte RFU3F = 0x3f;
        private const byte RxModeReg = 0x13;
        private const byte RxSelReg = 0x17;
        private const byte RxThresholdReg = 0x18;
        private SerialPort serialport;
        private const byte SerialSpeedReg = 0x1f;
        private const byte Status1Reg = 7;
        private const byte Status2Reg = 8;
        private const byte TCounterValueRegH = 0x2e;
        private const byte TCounterValueRegL = 0x2f;
        private const byte TestADCReg = 0x3b;
        private const byte TestBusReg = 0x35;
        private const byte TestDAC1Reg = 0x39;
        private const byte TestDAC2Reg = 0x3a;
        private const byte TestPinEnReg = 0x33;
        private const byte TestPinValueReg = 0x34;
        private const byte TestSel1Reg = 0x31;
        private const byte TestSel2Reg = 50;
        private const byte TModeReg = 0x2a;
        private const byte TPrescalerReg = 0x2b;
        private const byte TReloadRegH = 0x2c;
        private const byte TReloadRegL = 0x2d;
        private const byte TxAutoReg = 0x15;
        private const byte TxControlReg = 20;
        private const byte TxModeReg = 0x12;
        private const byte TxSelReg = 0x16;
        private const byte VersionReg = 0x37;
        private const byte WaterLevelReg = 11;
        
        public StatusCode BackupPurse(byte Source, byte Destination)
        {
            if (!this.IsOpen)
            {
                return StatusCode.PortErr;
            }
            StatusCode paraErr = StatusCode.ParaErr;
            if ((Source % 4) == 3)
            {
                return paraErr;
            }
            if ((Destination % 4) == 3)
            {
                return paraErr;
            }
            try
            {
                byte[] buffer2;
                byte[] data = new byte[4];
                data[0] = 0xc2;
                data[1] = Source;
                ushort num = CRC16Rev.CalculateCRC16(data, 0, 2, 0x6363, 0x8408);
                data[2] = (byte) (num % 0x100);
                data[3] = (byte) (num / 0x100);
                paraErr = this.PcdComMF522(12, data, out buffer2);
                if (paraErr != StatusCode.AllDone)
                {
                    return paraErr;
                }
                if ((buffer2.Length != 1) || ((buffer2[0] & 15) != 10))
                {
                    return StatusCode.DataLengthErr;
                }
                data = new byte[6];
                num = CRC16Rev.CalculateCRC16(data, 0, 4, 0x6363, 0x8408);
                data[4] = (byte) (num % 0x100);
                data[5] = (byte) (num / 0x100);
                paraErr = this.PcdComMF522(12, data, out buffer2);
                if (paraErr != StatusCode.AllDone)
                {
                    return paraErr;
                }
                data = new byte[4];
                data[0] = 0xb0;
                data[1] = Destination;
                num = CRC16Rev.CalculateCRC16(data, 0, 2, 0x6363, 0x8408);
                data[2] = (byte) (num % 0x100);
                data[3] = (byte) (num / 0x100);
                paraErr = this.PcdComMF522(12, data, out buffer2);
                if (paraErr != StatusCode.AllDone)
                {
                    return paraErr;
                }
                if ((buffer2.Length != 1) || ((buffer2[0] & 15) != 10))
                {
                    return StatusCode.DataLengthErr;
                }
                return StatusCode.AllDone;
            }
            catch
            {
                return StatusCode.ComErr;
            }
        }
        
        private StatusCode CalulateCRC(ref byte[] DataBuffer, int index, int Length)
        {
            if (!this.IsOpen)
            {
                return StatusCode.PortErr;
            }
            try
            {
                this.ClearBitMask(5, 4);
                this.WriteRawRC(1, 0);
                this.SetBitMask(10, 0x80);
                for (int i = 0; i < Length; i++)
                {
                    this.WriteRawRC(9, DataBuffer[index + i]);
                }
                this.WriteRawRC(1, 3);
                Thread.Sleep(0x19);
                DataBuffer[index + Length] = this.ReadRawRC(0x22);
                DataBuffer[(index + Length) + 1] = this.ReadRawRC(0x21);
                return StatusCode.AllDone;
            }
            catch
            {
                return StatusCode.ComErr;
            }
        }
        
        public StatusCode ChangeBaudRate(int BaudRate)
        {
            if (!this.serialport.IsOpen)
            {
                return StatusCode.PortErr;
            }
            if (this.serialport.BaudRate == BaudRate)
            {
                return StatusCode.AllDone;
            }
            ArrayList list = new ArrayList(new int[] { 0x1c20, 0x2580, 0x3840, 0x4b00, 0x9600, 0xe100, 0x1c200, 0x1f400, 0x38400, 0x70800, 0xe1000, 0x12c000 });
            byte[] buffer = new byte[] { 250, 0xeb, 0xda, 0xcb, 0xab, 0x9a, 0x7a, 0x74, 90, 0x3a, 0x1c, 0x15 };
            int index = list.IndexOf(BaudRate);
            if ((index < 0) || (index > 11))
            {
                return StatusCode.ParaErr;
            }
            try
            {
                this.WriteRawRC(0x1f, buffer[index]);
                this.serialport.BaudRate = BaudRate;
                return StatusCode.AllDone;
            }
            catch
            {
                return StatusCode.PortErr;
            }
        }
        
        private void ClearBitMask(byte Address, byte Mask)
        {
            byte num = this.ReadRawRC(Address);
            this.WriteRawRC(Address, (byte) (num & ~Mask));
        }
        
        public StatusCode CloseSerialPort()
        {
            if (!this.IsOpen)
            {
                return StatusCode.AllDone;
            }
            try
            {
                this.WriteRawRC(0x1f, 0xeb);
            }
            catch
            {
            }
            try
            {
                this.serialport.Close();
            }
            catch
            {
            }
            if (!this.IsOpen)
            {
                this.serialport = null;
                return StatusCode.AllDone;
            }
            return StatusCode.PortErr;
        }
        
        public StatusCode EnableBuzzer(bool flag)
        {
            if (!this.IsOpen)
            {
                return StatusCode.PortErr;
            }
            try
            {
                if (flag)
                {
                    this.ClearBitMask(0x34, 0x10);
                }
                else
                {
                    this.SetBitMask(0x34, 0x10);
                }
                return StatusCode.AllDone;
            }
            catch
            {
                return StatusCode.PortErr;
            }
        }
        
        public StatusCode EnableLEDAct(bool flag)
        {
            if (!this.IsOpen)
            {
                return StatusCode.PortErr;
            }
            try
            {
                if (flag)
                {
                    this.SetBitMask(0x34, 4);
                }
                else
                {
                    this.ClearBitMask(0x34, 4);
                }
                return StatusCode.AllDone;
            }
            catch
            {
                return StatusCode.PortErr;
            }
        }
        
        public StatusCode EnableLEDUser(bool flag)
        {
            if (!this.IsOpen)
            {
                return StatusCode.PortErr;
            }
            try
            {
                if (flag)
                {
                    this.SetBitMask(0x34, 8);
                }
                else
                {
                    this.ClearBitMask(0x34, 8);
                }
                return StatusCode.AllDone;
            }
            catch
            {
                return StatusCode.PortErr;
            }
        }
        
        public StatusCode OpenSerialPort(string PortName)
        {
            if (this.IsOpen)
            {
                if (this.serialport.PortName.Equals(PortName))
                {
                    return StatusCode.AllDone;
                }
                this.serialport.Close();
            }
            try
            {
                this.serialport = new SerialPort(PortName);
                this.serialport.BaudRate = 0x2580;
                this.serialport.DataBits = 8;
                this.serialport.StopBits = StopBits.One;
                this.serialport.Parity = Parity.None;
                this.serialport.WriteTimeout = 50;
                this.serialport.ReadTimeout = 0x3e8;
                this.serialport.Open();
                if (this.IsOpen)
                {
                    return StatusCode.AllDone;
                }
                return StatusCode.PortErr;
            }
            catch
            {
                return StatusCode.PortErr;
            }
        }
        
        private void PcdAntennaOff()
        {
            this.ClearBitMask(20, 3);
        }
        
        private void PcdAntennaOn()
        {
            this.SetBitMask(20, 3);
        }
        
        public StatusCode PcdAnticoll(out byte[] TagNumber)
        {
            TagNumber = new byte[4];
            if (!this.IsOpen)
            {
                return StatusCode.PortErr;
            }
            try
            {
                byte[] buffer;
                this.ClearBitMask(8, 8);
                this.WriteRawRC(13, 0);
                this.ClearBitMask(14, 0x80);
                byte[] inData = new byte[] { 0x93, 0x20 };
                StatusCode code = this.PcdComMF522(12, inData, out buffer);
                this.SetBitMask(14, 0x80);
                if (code != StatusCode.AllDone)
                {
                    return code;
                }
                if (buffer.Length == 5)
                {
                    byte num = 0;
                    for (int i = 0; i < 4; i++)
                    {
                        num = (byte) (num ^ buffer[i]);
                        TagNumber[i] = buffer[i];
                    }
                    if (num != buffer[4])
                    {
                        return StatusCode.ParityErr;
                    }
                    return StatusCode.AllDone;
                }
                return StatusCode.DataLengthErr;
            }
            catch
            {
                return StatusCode.ComErr;
            }
        }
        
        public StatusCode PcdAnticoll2(out byte[] TagNumber)
        {
            TagNumber = new byte[4];
            if (!this.IsOpen)
            {
                return StatusCode.PortErr;
            }
            bool flag = false;
            byte num = 0;
            byte num2 = 0x93;
            this.ClearBitMask(8, 8);
            this.WriteRawRC(13, 0);
            this.ClearBitMask(14, 0x80);
            while (!flag)
            {
                byte num5;
                byte num4 = (byte) (num / 8);
                byte num7 = (byte) (num % 8);
                byte num3 = (byte) ((0x20 + (num4 << 4)) | num7);
                this.WriteRawRC(4, 4);
                this.WriteRawRC(1, 0);
                this.SetBitMask(10, 0x80);
                this.WriteRawRC(9, num2);
                this.WriteRawRC(9, num3);
                if (num7 > 0)
                {
                    num5 = (byte) (num4 + 1);
                }
                else
                {
                    num5 = num4;
                }
                int index = 0;
                while (index < num5)
                {
                    this.WriteRawRC(9, TagNumber[index]);
                    index++;
                }
                this.WriteRawRC(1, 12);
                this.WriteRawRC(13, (byte) ((num7 << 4) | num7));
                this.SetBitMask(13, 0x80);
                Thread.Sleep(200);
                this.ClearBitMask(13, 0x80);
                if ((this.ReadRawRC(4) & 1) > 0)
                {
                    this.SetBitMask(14, 0x80);
                    return StatusCode.NoTagErr;
                }
                byte num9 = this.ReadRawRC(6);
                if ((num9 & 1) > 0)
                {
                    this.SetBitMask(14, 0x80);
                    return StatusCode.ProtocolErr;
                }
                if ((num9 & 2) > 0)
                {
                    this.SetBitMask(14, 0x80);
                    return StatusCode.ParityErr;
                }
                if ((num9 & 4) > 0)
                {
                    this.SetBitMask(14, 0x80);
                    return StatusCode.CRCErr;
                }
                if ((num9 & 0x40) > 0)
                {
                    this.SetBitMask(14, 0x80);
                    return StatusCode.TempErr;
                }
                if ((num9 & 0x80) > 0)
                {
                    this.SetBitMask(14, 0x80);
                    return StatusCode.WriteErr;
                }
                byte num6 = this.ReadRawRC(10);
                byte num8 = (byte) (this.ReadRawRC(12) & 7);
                if (num6 == 0)
                {
                    num6 = 1;
                }
                byte[] buffer = new byte[7];
                index = 0;
                while (index < num6)
                {
                    buffer[index] = this.ReadRawRC(9);
                    index++;
                }
                for (index = 0; index < (4 - num4); index++)
                {
                    TagNumber[num4 + index] = (byte) (TagNumber[num4 + index] | buffer[index]);
                }
                if ((num9 & 8) > 0)
                {
                    byte num10 = this.ReadRawRC(14);
                    if ((num10 & 0x20) > 0)
                    {
                        this.SetBitMask(14, 0x80);
                        return StatusCode.OtherErr;
                    }
                    num10 = (byte) (num10 & 0x1f);
                    num = (byte) (num + num10);
                    if (num >= 0x20)
                    {
                        flag = true;
                    }
                }
                else
                {
                    flag = true;
                }
            }
            this.SetBitMask(14, 0x80);
            return StatusCode.AllDone;
        }
        
        public StatusCode PcdAuthState(byte auth_mode, byte Address, byte[] Key, byte[] TagNumber)
        {
            if (!this.IsOpen)
            {
                return StatusCode.PortErr;
            }
            try
            {
                int num;
                byte[] buffer2;
                StatusCode paraErr = StatusCode.ParaErr;
                if (Key.Length != 6)
                {
                    return paraErr;
                }
                if (TagNumber.Length < 4)
                {
                    return paraErr;
                }
                byte[] inData = new byte[12];
                inData[0] = auth_mode;
                inData[1] = Address;
                for (num = 0; num < 6; num++)
                {
                    inData[2 + num] = Key[num];
                }
                for (num = 0; num < 4; num++)
                {
                    inData[8 + num] = TagNumber[num];
                }
                paraErr = this.PcdComMF522(14, inData, out buffer2);
                byte num2 = this.ReadRawRC(8);
                if (paraErr != StatusCode.AllDone)
                {
                    return paraErr;
                }
                if ((num2 & 8) == 0)
                {
                    return StatusCode.AuthErr;
                }
                return StatusCode.AllDone;
            }
            catch
            {
                return StatusCode.ComErr;
            }
        }
        
        private StatusCode PcdComMF522(byte Command, byte[] InData, out byte[] OutData)
        {
            OutData = new byte[0];
            if (!this.IsOpen)
            {
                return StatusCode.PortErr;
            }
            try
            {
                int num;
                StatusCode comErr = StatusCode.ComErr;
                this.ClearBitMask(4, 0x80);
                this.WriteRawRC(1, 0);
                this.SetBitMask(10, 0x80);
                for (num = 0; num < InData.Length; num++)
                {
                    this.WriteRawRC(9, InData[num]);
                }
                this.WriteRawRC(1, Command);
                if (Command == 12)
                {
                    this.SetBitMask(13, 0x80);
                }
                Thread.Sleep(0x19);
                this.ClearBitMask(13, 0x80);
                byte errorRegValue = this.ReadRawRC(6);
                if (errorRegValue == 0)
                {
                    comErr = StatusCode.AllDone;
                    if (Command == 12)
                    {
                        byte num3 = this.ReadRawRC(10);
                        OutData = new byte[num3];
                        for (num = 0; num < num3; num++)
                        {
                            OutData[num] = this.ReadRawRC(9);
                        }
                    }
                }
                else
                {
                    comErr = this.PhaseErrorRegValue(errorRegValue);
                }
                this.WriteRawRC(1, 0);
                this.WriteRawRC(10, 0x80);
                return comErr;
            }
            catch
            {
                return StatusCode.ComErr;
            }
        }
        
        private StatusCode PcdComMF522(byte Command, byte[] InData, int InDatabits, out byte[] OutData, out int OutDataBits)
        {
            OutData = new byte[0];
            OutDataBits = 0;
            if (!this.IsOpen)
            {
                return StatusCode.PortErr;
            }
            try
            {
                int num;
                byte num2;
                int num4;
                StatusCode comErr = StatusCode.ComErr;
                this.WriteRawRC(4, 0x7f);
                this.WriteRawRC(1, 0);
                this.SetBitMask(10, 0x80);
                for (num = 0; num < InData.Length; num++)
                {
                    this.WriteRawRC(9, InData[num]);
                }
                this.WriteRawRC(1, Command);
                if (Command == 12)
                {
                    this.SetBitMask(13, 0x80);
                }
                Thread.Sleep(200);
                if ((this.ReadRawRC(4) & 1) > 0)
                {
                    return StatusCode.NoTagErr;
                }
                this.ClearBitMask(13, 0x80);
                byte errorRegValue = (byte) (this.ReadRawRC(6) & 0x1b);
                if (errorRegValue == 0)
                {
                    comErr = StatusCode.AllDone;
                    if (Command == 12)
                    {
                        num2 = this.ReadRawRC(10);
                        num4 = this.ReadRawRC(12) & 7;
                        if (num4 > 0)
                        {
                            OutDataBits = ((num2 - 1) * 8) + num4;
                        }
                        else
                        {
                            OutDataBits = num2 * 8;
                        }
                        if (num2 == 0)
                        {
                            num2 = 1;
                        }
                        OutData = new byte[num2];
                        for (num = 0; num < num2; num++)
                        {
                            OutData[num] = this.ReadRawRC(9);
                        }
                    }
                }
                else
                {
                    comErr = this.PhaseErrorRegValue(errorRegValue);
                    if (Command == 12)
                    {
                        num2 = this.ReadRawRC(10);
                        num4 = this.ReadRawRC(12) & 7;
                        if (num4 > 0)
                        {
                            OutDataBits = ((num2 - 1) * 8) + num4;
                        }
                        else
                        {
                            OutDataBits = num2 * 8;
                        }
                        if (num2 == 0)
                        {
                            num2 = 1;
                        }
                        OutData = new byte[num2];
                        for (num = 0; num < num2; num++)
                        {
                            OutData[num] = this.ReadRawRC(9);
                        }
                    }
                }
                this.WriteRawRC(1, 0);
                this.WriteRawRC(10, 0x80);
                return comErr;
            }
            catch
            {
                return StatusCode.ComErr;
            }
        }
        
        public StatusCode PcdDecrease(byte Address, int Value)
        {
            if (!this.IsOpen)
            {
                return StatusCode.PortErr;
            }
            StatusCode paraErr = StatusCode.ParaErr;
            if ((Address % 4) == 3)
            {
                return paraErr;
            }
            return this.PcdValue(0xc0, Address, BitConverter.GetBytes(Value));
        }
        
        public StatusCode PcdHalt()
        {
            if (!this.IsOpen)
            {
                return StatusCode.PortErr;
            }
            try
            {
                byte[] buffer2;
                byte[] data = new byte[4];
                data[0] = 80;
                data[1] = 0;
                ushort num = CRC16Rev.CalculateCRC16(data, 0, 2, 0x6363, 0x8408);
                data[2] = (byte) (num % 0x100);
                data[3] = (byte) (num / 0x100);
                this.ClearBitMask(8, 8);
                StatusCode code = this.PcdComMF522(12, data, out buffer2);
                if (code != StatusCode.AllDone)
                {
                    return code;
                }
                return StatusCode.AllDone;
            }
            catch
            {
                return StatusCode.ComErr;
            }
        }
        
        public StatusCode PcdIncrease(byte Address, int Value)
        {
            if (!this.IsOpen)
            {
                return StatusCode.PortErr;
            }
            StatusCode paraErr = StatusCode.ParaErr;
            if ((Address % 4) == 3)
            {
                return paraErr;
            }
            return this.PcdValue(0xc1, Address, BitConverter.GetBytes(Value));
        }
        
        public StatusCode PcdIntPurse(byte Address)
        {
            if (!this.IsOpen)
            {
                return StatusCode.PortErr;
            }
            StatusCode paraErr = StatusCode.ParaErr;
            if ((Address % 4) == 3)
            {
                return paraErr;
            }
            try
            {
                byte[] buffer2 = new byte[] { 0, 0, 0, 0, 0xff, 0xff, 0xff, 0xff, 0, 0, 0, 0, 0, 0, 0, 0 };
                buffer2[12] = Address;
                buffer2[13] = Convert.ToByte(~Address);
                buffer2[14] = Address;
                buffer2[15] = Convert.ToByte(~Address);
                byte[] data = buffer2;
                return this.PcdWrite(Address, data);
            }
            catch
            {
                return StatusCode.ComErr;
            }
        }
        
        public StatusCode PcdRead(byte Address, out byte[] Data)
        {
            Data = new byte[0x10];
            if (!this.IsOpen)
            {
                return StatusCode.PortErr;
            }
            try
            {
                byte[] buffer2;
                byte[] data = new byte[4];
                data[0] = 0x30;
                data[1] = Address;
                ushort num = CRC16Rev.CalculateCRC16(data, 0, 2, 0x6363, 0x8408);
                data[2] = (byte) (num % 0x100);
                data[3] = (byte) (num / 0x100);
                StatusCode code = this.PcdComMF522(12, data, out buffer2);
                if (code != StatusCode.AllDone)
                {
                    return code;
                }
                if (buffer2.Length < 0x10)
                {
                    return StatusCode.DataLengthErr;
                }
                for (int i = 0; i < 0x10; i++)
                {
                    Data[i] = buffer2[i];
                }
                return StatusCode.AllDone;
            }
            catch
            {
                return StatusCode.ComErr;
            }
        }
        
        public StatusCode PcdReadPurse(byte Address, out int Value)
        {
            Value = 0;
            if (!this.IsOpen)
            {
                return StatusCode.PortErr;
            }
            StatusCode paraErr = StatusCode.ParaErr;
            if ((Address % 4) == 3)
            {
                return paraErr;
            }
            try
            {
                byte[] buffer;
                paraErr = this.PcdRead(Address, out buffer);
                if (paraErr != StatusCode.AllDone)
                {
                    return paraErr;
                }
                if (buffer[12] != ~buffer[13])
                {
                    return StatusCode.PurseFormatErr;
                }
                if (buffer[12] != buffer[14])
                {
                    return StatusCode.PurseFormatErr;
                }
                if (buffer[13] != buffer[15])
                {
                    return StatusCode.PurseFormatErr;
                }
                Value = BitConverter.ToInt32(buffer, 0);
                if (Value != ~BitConverter.ToInt32(buffer, 4))
                {
                    return StatusCode.PurseFormatErr;
                }
                if (Value != BitConverter.ToInt32(buffer, 8))
                {
                    return StatusCode.PurseFormatErr;
                }
                return StatusCode.AllDone;
            }
            catch
            {
                return StatusCode.ComErr;
            }
        }
        
        public StatusCode PcdRequest(byte req_code, out byte[] TagType)
        {
            TagType = new byte[2];
            if (!this.IsOpen)
            {
                return StatusCode.PortErr;
            }
            try
            {
                byte[] buffer;
                this.ClearBitMask(8, 8);
                this.WriteRawRC(13, 7);
                this.SetBitMask(20, 3);
                byte[] inData = new byte[] { req_code };
                StatusCode code = this.PcdComMF522(12, inData, out buffer);
                if (code != StatusCode.AllDone)
                {
                    return code;
                }
                if (buffer.Length == 2)
                {
                    TagType[0] = buffer[0];
                    TagType[1] = buffer[1];
                    return StatusCode.AllDone;
                }
                return StatusCode.NoTagErr;
            }
            catch
            {
                return StatusCode.ComErr;
            }
        }
        
        public StatusCode PcdSelect(byte[] TagNumber)
        {
            if (!this.IsOpen)
            {
                return StatusCode.PortErr;
            }
            try
            {
                byte[] buffer2;
                byte[] data = new byte[9];
                data[0] = 0x93;
                data[1] = 0x70;
                for (int i = 0; i < 4; i++)
                {
                    data[i + 2] = TagNumber[i];
                    data[6] = (byte) (data[6] ^ TagNumber[i]);
                }
                ushort num2 = CRC16Rev.CalculateCRC16(data, 0, 7, 0x6363, 0x8408);
                data[7] = (byte) (num2 % 0x100);
                data[8] = (byte) (num2 / 0x100);
                this.ClearBitMask(8, 8);
                StatusCode code = this.PcdComMF522(12, data, out buffer2);
                if (code != StatusCode.AllDone)
                {
                    return code;
                }
                return StatusCode.AllDone;
            }
            catch
            {
                return StatusCode.ComErr;
            }
        }
        
        private StatusCode PcdValue(byte Mode, byte Address, byte[] Value)
        {
            if (!this.IsOpen)
            {
                return StatusCode.PortErr;
            }
            try
            {
                byte[] buffer2;
                StatusCode paraErr = StatusCode.ParaErr;
                if ((Address % 4) == 3)
                {
                    return paraErr;
                }
                byte[] data = new byte[4];
                data[0] = Mode;
                data[1] = Address;
                ushort num = CRC16Rev.CalculateCRC16(data, 0, 2, 0x6363, 0x8408);
                data[2] = (byte) (num % 0x100);
                data[3] = (byte) (num / 0x100);
                paraErr = this.PcdComMF522(12, data, out buffer2);
                if (paraErr != StatusCode.AllDone)
                {
                    return paraErr;
                }
                if ((buffer2.Length != 1) || ((buffer2[0] & 15) != 10))
                {
                    return StatusCode.DataLengthErr;
                }
                data = new byte[6];
                for (int i = 0; i < 4; i++)
                {
                    data[i] = Value[i];
                }
                num = CRC16Rev.CalculateCRC16(data, 0, 4, 0x6363, 0x8408);
                data[4] = (byte) (num % 0x100);
                data[5] = (byte) (num / 0x100);
                paraErr = this.PcdComMF522(12, data, out buffer2);
                if (paraErr != StatusCode.AllDone)
                {
                    return paraErr;
                }
                data = new byte[4];
                data[0] = 0xb0;
                data[1] = Address;
                num = CRC16Rev.CalculateCRC16(data, 0, 2, 0x6363, 0x8408);
                data[2] = (byte) (num % 0x100);
                data[3] = (byte) (num / 0x100);
                paraErr = this.PcdComMF522(12, data, out buffer2);
                if (paraErr != StatusCode.AllDone)
                {
                    return paraErr;
                }
                if ((buffer2.Length != 1) || ((buffer2[0] & 15) != 10))
                {
                    return StatusCode.DataLengthErr;
                }
                return StatusCode.AllDone;
            }
            catch
            {
                return StatusCode.ComErr;
            }
        }
        
        public StatusCode PcdWrite(byte Address, byte[] Data)
        {
            if (!this.IsOpen)
            {
                return StatusCode.PortErr;
            }
            if (Data.Length != 0x10)
            {
                return StatusCode.ParaErr;
            }
            try
            {
                byte[] buffer2;
                byte[] data = new byte[4];
                data[0] = 160;
                data[1] = Address;
                ushort num = CRC16Rev.CalculateCRC16(data, 0, 2, 0x6363, 0x8408);
                data[2] = (byte) (num % 0x100);
                data[3] = (byte) (num / 0x100);
                StatusCode code = this.PcdComMF522(12, data, out buffer2);
                if (code != StatusCode.AllDone)
                {
                    return code;
                }
                if ((buffer2.Length != 1) || ((buffer2[0] & 15) != 10))
                {
                    return StatusCode.DataLengthErr;
                }
                data = new byte[0x12];
                for (int i = 0; i < 0x10; i++)
                {
                    data[i] = Data[i];
                }
                num = CRC16Rev.CalculateCRC16(data, 0, 0x10, 0x6363, 0x8408);
                data[0x10] = (byte) (num % 0x100);
                data[0x11] = (byte) (num / 0x100);
                code = this.PcdComMF522(12, data, out buffer2);
                if (code != StatusCode.AllDone)
                {
                    return code;
                }
                if ((buffer2.Length != 1) || ((buffer2[0] & 15) != 10))
                {
                    return StatusCode.DataLengthErr;
                }
                return StatusCode.AllDone;
            }
            catch
            {
                return StatusCode.ComErr;
            }
        }
        
        private StatusCode PhaseErrorRegValue(byte ErrorRegValue)
        {
            if ((ErrorRegValue & 1) > 0)
            {
                return StatusCode.ProtocolErr;
            }
            if ((ErrorRegValue & 2) > 0)
            {
                return StatusCode.ParityErr;
            }
            if ((ErrorRegValue & 4) > 0)
            {
                return StatusCode.CRCErr;
            }
            if ((ErrorRegValue & 8) > 0)
            {
                return StatusCode.CollErr;
            }
            if ((ErrorRegValue & 0x40) > 0)
            {
                return StatusCode.TempErr;
            }
            if ((ErrorRegValue & 0x80) > 0)
            {
                return StatusCode.WriteErr;
            }
            return StatusCode.ComErr;
        }
        
        private byte ReadRawRC(byte Address)
        {
            byte[] buffer = new byte[] { (byte) (Address | 0x80) };
            this.serialport.Write(buffer, 0, 1);
            return (byte) this.serialport.ReadByte();
        }
        
        public StatusCode RestartReader()
        {
            if (!this.serialport.IsOpen)
            {
                return StatusCode.PortErr;
            }
            try
            {
                this.WriteRawRC(1, 0);
                Thread.Sleep(20);
                this.WriteRawRC(1, 15);
                this.serialport.BaudRate = 0x2580;
                Thread.Sleep(20);
                this.WriteRawRC(0x11, 0x3d);
                this.WriteRawRC(0x2d, 30);
                this.WriteRawRC(0x2c, 0);
                this.WriteRawRC(0x2a, 0x8d);
                this.WriteRawRC(0x2b, 0x3e);
                this.WriteRawRC(0x15, 0x40);
                this.WriteRawRC(0x26, 0x70);
                this.PcdAntennaOff();
                this.EnableLEDUser(false);
                this.EnableLEDAct(false);
                this.EnableBuzzer(false);
                this.ClearBitMask(8, 8);
                this.WriteRawRC(0x11, 0x3d);
                this.WriteRawRC(0x17, 0x86);
                this.WriteRawRC(0x26, 0x7f);
                this.WriteRawRC(0x2d, 30);
                this.WriteRawRC(0x2c, 0);
                this.WriteRawRC(0x2a, 0x8d);
                this.WriteRawRC(0x2b, 0x3e);
                Thread.Sleep(100);
                this.PcdAntennaOn();
                return StatusCode.AllDone;
            }
            catch
            {
                return StatusCode.PortErr;
            }
        }
        
        private void SetBitMask(byte Address, byte Mask)
        {
            byte num = this.ReadRawRC(Address);
            this.WriteRawRC(Address, (byte) (num | Mask));
        }
        
        public StatusCode TestReader()
        {
            if (!this.IsOpen)
            {
                return StatusCode.PortErr;
            }
            try
            {
                byte num = this.ReadRawRC(0);
                return StatusCode.AllDone;
            }
            catch
            {
                return StatusCode.PortErr;
            }
        }
        
        private void WriteRawRC(byte Address, byte Value)
        {
            byte[] buffer = new byte[] { (byte) (Address & 0x7f), Value };
            this.serialport.Write(buffer, 0, 1);
            this.serialport.ReadByte();
            this.serialport.Write(buffer, 1, 1);
        }
        
        public bool IsOpen
        {
            //get
            //{
            //    try
            //    {
            //        return this.serialport.IsOpen;
            //    }
            //    catch
            //    {
            //        return false;
            //    }
            //}
            get { return serialport != null && serialport.IsOpen; }
        }
        
        public enum StatusCode
        {
            AllDone = 0,
            AuthErr = 6,
            BufferOvfl = 0x15,
            CollErr = 20,
            ComErr = 2,
            CRCErr = 0x13,
            DataLengthErr = 4,
            NoTagErr = 7,
            OtherErr = 0xff,
            ParaErr = 3,
            ParityErr = 0x12,
            PortErr = 1,
            ProtocolErr = 0x11,
            PurseFormatErr = 5,
            TempErr = 0x16,
            WriteErr = 0x17
        }
    }
}
